package org.hdlh.handler;

import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import org.hdlh.constants.ReqType;
import org.hdlh.core.Header;
import org.hdlh.core.RpcProtocol;
import org.hdlh.core.RpcRequest;
import org.hdlh.core.RpcResponse;
import org.hdlh.spring.SpringBeanManger;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class RpcServerHandler extends SimpleChannelInboundHandler<RpcProtocol<RpcRequest>> {


    @Override
    protected void channelRead0(ChannelHandlerContext channelHandlerContext, RpcProtocol<RpcRequest> rpcRequestRpcProtocol) throws Exception {
        RpcProtocol resRpcProtocol = new RpcProtocol();
        Header header = rpcRequestRpcProtocol.getHeader();
        header.setReqType(ReqType.RESPONSE.code());
        Object result = invoke(rpcRequestRpcProtocol.getContent());
        resRpcProtocol.setHeader(header);
        RpcResponse rpcResponse = new RpcResponse();
        rpcResponse.setData(result);
        rpcResponse.setMsg("success");
        resRpcProtocol.setContent(rpcResponse);
        channelHandlerContext.writeAndFlush(resRpcProtocol);
    }


    public Object invoke(RpcRequest rpcRequest){
        try {
            Class<?> clazz = Class.forName(rpcRequest.getClassName());
            Object bean = SpringBeanManger.getBean(clazz);
            Method method = clazz.getDeclaredMethod(rpcRequest.getMethodName(), rpcRequest.getParameterTypes());
            return method.invoke(bean, rpcRequest.getParams());
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        return null;
    }
}
